/*
 * Copyright 2017-2020 吴学文 and java110 team.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.java110.mall.user.impl;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.java110.core.client.RestTemplate;
import com.java110.core.factory.AuthenticationFactory;
import com.java110.dto.PageDto;
import com.java110.dto.community.CommunityDto;
import com.java110.dto.user.UserDto;
import com.java110.intf.user.IUserV1InnerServiceSMO;
import com.java110.intf.user.IWuyeV1InnerServiceSMO;
import com.java110.mall.user.dao.IUserV1ServiceDao;
import com.java110.po.user.PropertyOwnerAcctDto;
import com.java110.po.user.PropertyOwnerDto;
import com.java110.po.user.UserPo;
import com.java110.utils.cache.CommonCache;
import com.java110.utils.cache.MappingCache;
import com.java110.utils.constant.CommonConstant;
import com.java110.utils.constant.StatusConstant;
import com.java110.utils.exception.CmdException;
import com.java110.utils.util.BeanConvertUtil;
import com.java110.utils.util.DateUtil;
import com.java110.utils.util.ListUtil;
import com.java110.utils.util.StringUtil;
import com.java110.vo.ResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * 类表述： 服务之前调用的接口实现类，不对外提供接口能力 只用于接口建调用
 * add by 吴学文 at 2023-02-11 00:34:41 mail: 928255095@qq.com
 * open source address: https://gitee.com/wuxw7/MicroCommunity
 * 官网：http://www.homecommunity.cn
 * 温馨提示：如果您对此文件进行修改 请不要删除原有作者及注释信息，请补充您的 修改的原因以及联系邮箱如下
 * // modify by 张三 at 2021-09-12 第10行在某种场景下存在某种bug 需要修复，注释10至20行 加入 20行至30行
 */
@RestController
public class WuyeV1InnerServiceSMOImpl implements IWuyeV1InnerServiceSMO {

    public static final String COMMON_URL = "/app/mall.openCommonApi";

    public static final String GET_TOKEN_URL = "/app/login.pcUserLogin";
    private static final String DEFAULT_WUYE_URL = "http://wuye.homecommunity.cn";
    public static final String WUYE_DOMAIN = "WUYE"; // 物联网域
    private static final String WUYE_TOKEN = "WUYE_TOKEN";


    @Autowired
    private RestTemplate outRestTemplate;


    /**
     * 查询业主信息
     *
     * @param propertyOwnerDto
     * @return
     */
    @Override
    public PropertyOwnerDto getOwner(@RequestBody PropertyOwnerDto propertyOwnerDto) {

        String wuyeSwitch = MappingCache.getValue(WUYE_DOMAIN, "WUYE_SWITCH");
        if (!"ON".equals(wuyeSwitch)) {
            return null;
        }

        JSONObject paramIn = new JSONObject();
        paramIn.put("mallApiCode", "queryOwnerCommunityImpl");
        paramIn.put("link", propertyOwnerDto.getOwnerTel());
        paramIn.put("ownerId", propertyOwnerDto.getOwnerId());
        ResultVo resultVo = post(COMMON_URL, paramIn);
        if (resultVo.getCode() != 0) {
            return null;
        }
        return BeanConvertUtil.covertBean(resultVo.getData(), PropertyOwnerDto.class);
    }

    @Override
    public ResultVo prestoreAccount(@RequestBody PropertyOwnerAcctDto propertyOwnerAcctDto) {
        String wuyeSwitch = MappingCache.getValue(WUYE_DOMAIN, "WUYE_SWITCH");
        if (!"ON".equals(wuyeSwitch)) {
            return null;
        }

        JSONObject paramIn = new JSONObject();
        paramIn.put("mallApiCode", "prestoreAccountImpl");
        paramIn.put("link", propertyOwnerAcctDto.getOwnerTel());
        paramIn.put("ownerId", propertyOwnerAcctDto.getOwnerId());
        paramIn.put("amount", propertyOwnerAcctDto.getAmount());
        paramIn.put("communityId", propertyOwnerAcctDto.getCommunityId());

        ResultVo resultVo = post(COMMON_URL, paramIn);

        return resultVo;
    }

    @Override
    public List<CommunityDto> getFreeCommunitys(@RequestBody CommunityDto communityDto) {

        String wuyeSwitch = MappingCache.getValue(WUYE_DOMAIN, "WUYE_SWITCH");
        if (!"ON".equals(wuyeSwitch)) {
            return null;
        }

        JSONObject paramIn = new JSONObject();
        paramIn.put("mallApiCode", "getFreeCommunitysImpl");
        paramIn.put("areaCode", communityDto.getAreaCode());
        paramIn.put("notInCommunityId", communityDto.getNotInCommunityId());

        ResultVo resultVo = post(COMMON_URL, paramIn);

        JSONArray communitys = (JSONArray) resultVo.getData();

        if (ListUtil.isNull(communitys)) {
            return null;
        }

        return BeanConvertUtil.covertBeanList(communitys, CommunityDto.class);
    }

    @Override
    public ResultVo getCommunitys(@RequestBody JSONObject reqJson) {

        String wuyeSwitch = MappingCache.getValue(WUYE_DOMAIN, "WUYE_SWITCH");
        if (!"ON".equals(wuyeSwitch)) {
            return new ResultVo(ResultVo.CODE_ERROR, "未部署商城");
        }

        reqJson.put("mallApiCode", "getCommunitysImpl");

        ResultVo resultVo = post(COMMON_URL, reqJson);

        return resultVo;
    }

    @Override
    public ResultVo getOwnerFees(@RequestBody String tel) {
        String wuyeSwitch = MappingCache.getValue(WUYE_DOMAIN, "WUYE_SWITCH");
        if (!"ON".equals(wuyeSwitch)) {
            return new ResultVo(ResultVo.CODE_ERROR, "未部署商城");
        }

        JSONObject reqJson = new JSONObject();
        reqJson.put("mallApiCode", "getOwnerFeeImpl");
        reqJson.put("tel", tel);

        ResultVo resultVo = post(COMMON_URL, reqJson);

        return resultVo;
    }


    public ResultVo post(String url, JSONObject paramIn) {
        url = getUrl(url);
        HttpHeaders header = getHeaders(url, paramIn.toJSONString(), HttpMethod.POST);
        HttpEntity<String> httpEntity = new HttpEntity<String>(paramIn.toJSONString(), header);
        ResponseEntity<String> tokenRes = outRestTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);

        String body = tokenRes.getBody();
        JSONObject paramOut = JSONObject.parseObject(body);

        if (paramOut.getIntValue("code") != ResultVo.CODE_OK) {
            //saveTranslateError(paramIn.getString("communityId"),paramIn.toJSONString(),body,url);
        }

        int total = 1;
        int records = 1;
        if (paramOut.containsKey("total")) {
            total = paramOut.getIntValue("total");
        }

        if (paramOut.containsKey("records")) {
            records = paramOut.getIntValue("records");
        }

        return new ResultVo(records, total, paramOut.getIntValue("code"), paramOut.getString("msg"), paramOut.get("data"));
    }


    private static String getUrl(String param) {
        String url = MappingCache.getValue(WUYE_DOMAIN, "WUYE_URL");

        if (StringUtil.isEmpty(url)) {
            return DEFAULT_WUYE_URL + param;
        }

        return url + param;
    }


    /**
     * 封装头信息
     *
     * @return
     */
    private HttpHeaders getHeaders(String url, String param, HttpMethod method) {
        HttpHeaders header = new HttpHeaders();
        header.add(CommonConstant.APP_ID.toLowerCase(), MappingCache.getValue(WUYE_DOMAIN, "WUYE_APP_ID"));
        header.add(CommonConstant.USER_ID.toLowerCase(), CommonConstant.ORDER_DEFAULT_USER_ID);
        header.add(CommonConstant.TRANSACTION_ID.toLowerCase(), UUID.randomUUID().toString());
        header.add(CommonConstant.REQUEST_TIME.toLowerCase(), DateUtil.getDefaultFormateTimeString(new Date()));
        createSign(header, method, url, param);
        header.add("Authorization", "Bearer " + getToken(false));
        return header;
    }

    public String getToken(boolean refreshAccessToken) {
        String token = CommonCache.getValue(WUYE_TOKEN);
        if (!StringUtil.isEmpty(token) && !refreshAccessToken) {
            return token;
        }

        String url = getUrl(GET_TOKEN_URL);

        String userName = MappingCache.getValue(WUYE_DOMAIN, "WUYE_USERNAME");
        String password = MappingCache.getValue(WUYE_DOMAIN, "WUYE_PASSWORD");
        JSONObject param = new JSONObject();
        param.put("username", userName);
        password = AuthenticationFactory.passwdMd5(password);
        param.put("passwd", password);

        HttpHeaders header = new HttpHeaders();
        header.add(CommonConstant.APP_ID.toLowerCase(), MappingCache.getValue(WUYE_DOMAIN, "WUYE_APP_ID"));
        header.add(CommonConstant.USER_ID.toLowerCase(), CommonConstant.ORDER_DEFAULT_USER_ID);
        header.add(CommonConstant.TRANSACTION_ID.toLowerCase(), UUID.randomUUID().toString());
        header.add(CommonConstant.REQUEST_TIME.toLowerCase(), DateUtil.getDefaultFormateTimeString(new Date()));
        createSign(header, HttpMethod.POST, url, param.toJSONString());
        HttpEntity<String> httpEntity = new HttpEntity<String>(param.toJSONString(), header);

        ResponseEntity<String> tokenRes = outRestTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);


        JSONObject paramOut = JSONObject.parseObject(tokenRes.getBody());
        if (paramOut.getIntValue("code") != 0) {
            throw new IllegalArgumentException("获取token失败" + tokenRes.getBody());
        }

        JSONArray data = paramOut.getJSONArray("data");
        if (ListUtil.isNull(data)) {
            throw new IllegalArgumentException("物业返回格式错误");
        }
        JSONObject tokenObj = data.getJSONObject(0);
        if (!tokenObj.containsKey("token")) {
            throw new IllegalArgumentException("获取token失败" + tokenRes.getBody());
        }

        token = tokenObj.getString("token");
        int expiresIn = 30 * 60; //todo 30分钟

        CommonCache.setValue(WUYE_TOKEN, token, expiresIn - 200);

        return token;
    }


    /**
     * 创建鉴权
     *
     * @param headers
     * @param httpMethod
     * @param url
     * @param param
     */
    public static void createSign(HttpHeaders headers, HttpMethod httpMethod, String url, String param) {
        String appId = headers.getFirst(CommonConstant.APP_ID);
        String transactionId = headers.getFirst(CommonConstant.TRANSACTION_ID);
        String requestTime = headers.getFirst(CommonConstant.REQUEST_TIME);
        String securityCode = MappingCache.getValue(WUYE_DOMAIN, "WUYE_SECURE");

        if (StringUtil.isEmpty(securityCode)) {
            return;
        }
        String paramStr = "";
        if (HttpMethod.GET == httpMethod) {
            paramStr = url.substring(url.indexOf("?"));
        } else {
            paramStr = param;
        }
        String sign = transactionId + requestTime + appId + paramStr + securityCode;
        headers.remove("sign");
        headers.add("sign", AuthenticationFactory.md5(sign));
    }
}
